package com.editors;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import com.data.DrawObject;
import com.data.LineData;
import com.data.Point3D;
import com.data.PolygonMesh;

public class Editor extends JFrame{
	
	public static PolygonMesh loadPointsFromFile(BufferedReader br,String tag){

		PolygonMesh pm=null;
		Vector lines=new Vector();
		Vector points=new Vector();

		try {
		


			String str=null;
			int rows=0;
			
			boolean read=false;
			
			while((str=br.readLine())!=null){
				
				if(str.indexOf("#")>=0 || str.length()==0)
					continue;
				
				if(str.indexOf(tag)>=0){
					read=!read;
				    continue;
				}	
				
				if(!read)
					continue;

				if(str.startsWith("P="))
					buildPoints(points,str.substring(2));
				else if(str.startsWith("L="))
					buildLines(lines,str.substring(2));


			}

			if(points.size()==0)
				return null;
			
			pm=new PolygonMesh(points,lines);
			
			//checkNormals();
		} catch (Exception e) {

			e.printStackTrace();
		}
		
		return pm;
	}
	
	public static void buildPoints(Vector points, String str) {

		StringTokenizer sttoken=new StringTokenizer(str,"_");

		while(sttoken.hasMoreElements()){

			String[] vals = sttoken.nextToken().split(",");

			Point3D p=new Point3D();

			p.x=Double.parseDouble(vals[0]);
			p.y=Double.parseDouble(vals[1]);
			p.z=Double.parseDouble(vals[2]);
			
			if(vals.length==4)
				p.data=vals[3];

			points.add(p);
		}




	}
	
	public static void buildLines(Vector lines, String str) {

		StringTokenizer sttoken=new StringTokenizer(str,"_");

		while(sttoken.hasMoreElements()){



			LineData ld=composeLineData(sttoken.nextToken());


			lines.add(ld);
		}

	}
	
	public static LineData composeLineData(String str) {
		
		
		str=str.substring(1+str.indexOf("\t"));
		
		String[] data=str.split(",");
		
		LineData ld=new LineData();
		
		ld.setTexture_index(Integer.parseInt(data[0]));
		
		for (int i = 1; i < data.length; i++) {
			
			
			ld.addIndex(Integer.parseInt(data[i]));
		}
		
		
		return ld;
	}
	
	public static BufferedImage[] loadImages() throws IOException {
		

		File directoryImg=new File("lib/textures");
		File[] files=directoryImg.listFiles();

		Vector wtextures=new Vector();

		for(int i=0;i<files.length;i++){
			if(files[i].getName().startsWith("world_texture_")
					&& 	!files[i].getName().startsWith("object3D_texture")	
					){

				wtextures.add(files[i]);

			}		
		}

		BufferedImage[] worldImages=new BufferedImage[wtextures.size()]; 

		for(int i=0;i<wtextures.size();i++){

			File file=(File) wtextures.elementAt(i);
			worldImages[i]=ImageIO.read(file);

		}
		
		return worldImages;
		
	}
	
	public static BufferedImage[] loadObjectImages() throws IOException {
		
		File directoryImg=new File("lib/objects");
		File[] files=directoryImg.listFiles();
		
		Vector vObjects=new Vector();
	
	
		for(int i=0;i<files.length;i++){
			if(files[i].getName().startsWith("object_image_")
					){
	
				vObjects.add(files[i]);
	
			}		
		}

		BufferedImage[] objectImages=new BufferedImage[vObjects.size()];
	
		for(int i=0;i<vObjects.size();i++){
	
			objectImages[i]=ImageIO.read(new File("lib/objects/object_image_"+i+".jpg"));

		}
		
		return objectImages;
	}
	
	public void saveLines(PolygonMesh pm,PrintWriter pr) {

		Vector lines=pm.polygonData;
		Vector points=PolygonMesh.fromArrayToVector(pm.points);


		try {

			pr.print("P=");

			for(int i=0;i<points.size();i++){

				Point3D p=(Point3D) points.elementAt(i);

				pr.print(decomposePoint(p));
				if(i<points.size()-1)
					pr.print("_");
			}	

			pr.print("\nL=");

			for(int i=0;i<lines.size();i++){

				LineData ld=(LineData) lines.elementAt(i);

				pr.print(decomposeLineData(ld));
				if(i<lines.size()-1)
					pr.print("_");
			}	
			pr.println();

		} catch (Exception e) {

			e.printStackTrace();
		}
	}
	

	public String decomposePoint(Point3D point) {

		String pstr=point.x+","+point.y+","+point.z;
		return pstr;
	}
	

	public String decomposeLineData(LineData ld) {
		
		String str=ld.getTexture_index()+",";
		
		for(int i=0;i<ld.size();i++){
			if(i>0)
				str+=",";
			str+=ld.getIndex(i);
			
		}
		
		return str;
	}
	
	public static Vector loadObjectsFromFile(BufferedReader br) {

		Vector objects=new Vector(); 


		try {

			boolean read=false;

			String str=null;

			while((str=br.readLine())!=null){
				if(str.indexOf("#")>=0 || str.length()==0)
					continue;

				if(str.indexOf("objects")>=0){
					read=!read;
					continue;				
				}	

				if(!read)
					continue;

				DrawObject dro=buildDrawObject(str);
				objects.add(dro);
			}


	
		} catch (Exception e) {

			e.printStackTrace();
		}


		return objects;
	}
	
	private static DrawObject buildDrawObject(String str) { 
		DrawObject dro=new DrawObject();

		StringTokenizer tok=new StringTokenizer(str,"_");
		dro.x=Double.parseDouble(tok.nextToken());
		dro.y=Double.parseDouble(tok.nextToken());
		dro.z=Double.parseDouble(tok.nextToken());
		dro.index=Integer.parseInt(tok.nextToken());

		return dro;
	}

	public void saveObjects(Vector objects, PrintWriter pw) {
		
		try {
		

			for(int i=0;i<objects.size();i++){

				DrawObject dro=(DrawObject) objects.elementAt(i);
				String str=dro.getX()+"_"+dro.getY()+"_"+dro.getZ()+"_"+dro.getIndex();
				pw.println(str);
			}
	

		} catch (Exception e) {

			e.printStackTrace();
		}
	}


}
